
#User imports
import globals
import enemyMidi
import friendMidi
#Panda specific imports for this module
from pandac.PandaModules import *
#To handle events
from direct.showbase.DirectObject import DirectObject 
from random import random


from pygame.tests import test_utils
from pygame.tests.test_utils import test_not_implemented, unittest
import pygame
import pygame.midi
import pygame.compat
from pygame.locals import *


from pandac.PandaModules import Point3 #@UnresolvedImport


# Incomplete listing:
COMMANDS = {0: "NOTE_OFF",
            1: "NOTE_ON",
            2: "KEY_AFTER_TOUCH",
            3: "CONTROLLER_CHANGE",
            4: "PROGRAM_CHANGE",
            5: "CHANNEL_AFTER_TOUCH",
            6: "PITCH_BEND"}
# Incomplete listing: this is the key to CONTROLLER_CHANGE events data1
CONTROLLER_CHANGES = {1: "MOD WHEEL",
                      2: "BREATH",
                      4: "FOOT",
                      5: "PORTAMENTO",
                      6: "DATA",
                      7: "VOLUME",
                      10: "PAN",
                      }
def midis2events(midis, device_id):
    """converts midi events to pygame events
    pygame.midi.midis2events(midis, device_id): return [Event, ...]

    Takes a sequence of midi events and returns list of pygame events.
    """
    evs = []
    for midi in midis:

        ((status,data1,data2,data3),timestamp) = midi
        if status == 0xFF:
            # pygame doesn't seem to get these, so I didn't decode
            command =  "META"
            channel = None
        else:
            try:
                command = COMMANDS[ (status & 0x70) >> 4]
            except:
                command = status & 0x70
            channel = status & 0x0F
        e = pygame.event.Event(pygame.midi.MIDIIN,
                               status=status,
                               command=command,
                               channel=channel+1,
                               data1=data1,
                               data2=data2,
                               timestamp=timestamp,
                               vice_id = device_id)
        evs.append( e )
    return evs

class midiListener(DirectObject):
    def __init__(self):

        pygame.init()
        pygame.midi.init()
        midichannel = None

    def test_get_device_info(self):
        an_in_id = pygame.midi.get_default_input_id()
        if an_in_id != -1:
            r = pygame.midi.get_device_info(an_in_id)
            print r
            # if r is None, it means that the id is out of range.
            try:
                interf, name, input, output, opened = r
            except TypeError:
                raise Exception(repr(r))


    def test_input(self):
        i = pygame.midi.get_default_input_id()
        if i != -1:
            self.midichannel = pygame.midi.Input(i)
            print self.midichannel
            taskMgr.add(self.callback,"midiListener")

    def callback(self,task):
        #print pygame.midi.time()
        if self.midichannel.poll():

            midievent = self.midichannel.read(16)
            pyevent = midis2events(midievent,0)

            for it in pyevent:
                #print globals.groMODEL.has_key(it.channel), it.command ,it.timestamp
                if globals.groMODEL.has_key(it.channel) and it.command == "NOTE_ON" and it.timestamp > 400 and it.data2 != 0:
                    if globals.groMODEL[it.channel]['kindofmidi'] == 'friend':
                        self.tmpEnemy = friendMidi.FriendMidi()
                        tmpName = 'bueno' + str(it.timestamp)
                    else:
                        self.tmpEnemy = enemyMidi.EnemyMidi()
                        tmpName = 'malo' + str(it.timestamp)

                    self.tmpEnemy.time = it.timestamp
                    self.tmpEnemy.duration = 20
                    self.tmpEnemy.offset = it.timestamp
                    self.tmpEnemy.model =globals.groMODEL[it.channel]['model']
                    self.tmpEnemy.anim = globals.groMODEL[it.channel]['anim']
                    self.tmpEnemy.type =globals.groMODEL[it.channel]['type']
                    self.tmpEnemy.snd = globals.groMODEL[it.channel]['snd']
                    self.tmpEnemy.coltype =globals.groMODEL[it.channel]['coltype']
                    self.tmpEnemy.colx = globals.groMODEL[it.channel]['colx']
                    self.tmpEnemy.coly =globals.groMODEL[it.channel]['coly']
                    self.tmpEnemy.colz =globals.groMODEL[it.channel]['colz']
                    self.tmpEnemy.channel = it.channel
                    self.tmpEnemy.volume = it.data2
                    self.tmpEnemy.key= it.data1
                    self.tmpEnemy.scorePoints = 100
                    self.tmpEnemy.channel = it.channel
                    self.tmpEnemy.velocity = it.data2
                    self.tmpEnemy.pitch = it.data1
                    self.tmpEnemy.init()
                    #print it, self.tmpEnemy.type,self.tmpEnemy.sound
                    
                    self.tmpEnemy.actor.setTag('enemy', tmpName)
                    globals.ENEMIES[tmpName] = self.tmpEnemy
                    globals.ENEMIES_MOUSE[tmpName] = self.tmpEnemy
                    self.tmpEnemy = None
        return task.cont